package mvc.bezier;

import java.awt.event.MouseEvent;

import org.geom.Maths;
import org.geom.Point2D;
import org.geom.Point3D;
import org.geom.curve.Curve;
import org.render.CurveRenderer2D;

import mvc.controller.MouseController;
import mvc.model.ModelCurve;
import mvc.view.ViewCurve;

public class ControllerBezier2D extends MouseController {

	//---------------------------------------------------------------------- class var
	
	private Point2D translationOffset;
	private Point3D controlPointInDrag;
	
	//---------------------------------------------------------------------- constructor
	
	public ControllerBezier2D(ModelCurve model, ViewCurve view, String param) {
		super(model, view, param);
	}

	//---------------------------------------------------------------------- notify model


	public void setControlPointOnModel(Point3D controlPoint, Point2D mousePoint) {
		if (param==CurveRenderer2D.X) {
			controlPoint.x = mousePoint.x - translationOffset.x;
			controlPoint.y = mousePoint.y - translationOffset.y;
		} 
		if (param==CurveRenderer2D.Y) {			
			controlPoint.z = mousePoint.x - translationOffset.x;
			controlPoint.y = mousePoint.y - translationOffset.y;
		} 
		if (param==CurveRenderer2D.Z) {
			controlPoint.x = mousePoint.x - translationOffset.x;
			controlPoint.z = mousePoint.y - translationOffset.y;
		}
	}
	
	//---------------------------------------------------------------------- interface

	public void mousePressed(MouseEvent e) {
		super.mousePressed(e);
		controlPointInDrag = checkMouseOnControlPoints(e.getX(), e.getY());
	}

	public void mouseDragged(MouseEvent e) {
		super.mouseDragged(e);
		mouseMoved(e);
		
		if(controlPointInDrag != null) {
			setControlPointOnModel(controlPointInDrag, new Point2D(e.getX(), e.getY()));
			model.notifyAllViews();
		}
		else  {
			view.setTranslate(deltax, deltay);
			view.repaint();
		}
	}
	
	public void mouseReleased(MouseEvent e) {
		controlPointInDrag = null;
	}
	
	@Override
	public void mouseMoved(MouseEvent e) {
		setCurrentTonModel(e.getY());
	}

	private void setCurrentTonModel(int y) {
		model.setCurrentPoint(Maths.mapProportion(y, 
									0, view.getHeight(), 
									0, (Curve.length-1)*model.getArc()));
		view.repaint();
	}
	
	//---------------------------------------------------------------------- privates
	private Point3D checkMouseOnControlPoints(float mouseX, float mouseY) {
		Point2D p2d;
		for(Point3D p : ((IModelBezier)this.model).getControlPoints()) {	
			p2d = view.transform3dTo2d(p);
			if( getPlanePoint(mouseX, mouseY, p2d.x, p2d.y))
				return p;
		}
		return null;
	}
	
	private boolean getPlanePoint(float x1, float y1, float x2, float y2) {
		int k = 5;
		
		translationOffset = view.getTranslate();
		
		if (x1-k < x2+translationOffset.x && x1+k > x2+translationOffset.x &&
			y1-k < y2+translationOffset.y && y1+k > y2+translationOffset.y) {
			return true;
		} else return false;
	}

}
